%% @author wenqi_zheng
%% @doc @todo Add description to bank_server.


-module(bank_server).
-behaviour(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-export([create_account/2]).

-define(YEAR_TIME, 10).
-define(YEAR_PAYMENT, 10).
%% ====================================================================
%% API functions
%% ====================================================================


%%'银行开户，并存入初始金额
-spec create_account(Name, Money) -> any() when
      Name :: atom(),
      Money :: integer().

create_account(Name, Money)->
    {ok, Pid} = gen_server:start_link(?MODULE, [Money], []),
    %% 假设年费为10
    Pid ! {yearly, ?YEAR_PAYMENT},
    erlang:register(Name, Pid).

% --------------------------------------------------------------------
% Callback
% --------------------------------------------------------------------

init([Money]) ->
    %% 与银行服务中心进行关联
    link(whereis(bank_center)),
    {ok, Money}.

handle_call(check, _From, Money) ->
    {reply, Money, Money};

handle_call(Request, _From, State) ->
    io:format("handle_call: ~p~n", [Request]),
    Reply = ok,
    {reply, Reply, State}.

handle_cast(Msg, State) ->
    io:format("handle_cast: ~p~n", [Msg]),
    {noreply, State}.

%%'存钱
handle_info({deposit, AddMoney}, Money) ->
    NewMoney = Money + AddMoney,
    io:format("deposit money: ~w -> ~w~n", [Money, NewMoney]),
    {noreply, NewMoney};
%%.

%%'取钱(可透支)
handle_info({cash1, SubMoney}, Money) ->
    NewMoney = Money - SubMoney,
    io:format("deposit money: ~w -> ~w~n", [Money, NewMoney]),
    {noreply, NewMoney};
%%.

%%'取钱(不可透支)
handle_info({cash2, SubMoney}, Money) ->
    NewMoney = Money - SubMoney,
    case NewMoney > 0 of
        true ->
            %% 支取成功
            io:format("deposit money: ~w -> ~w", [Money, NewMoney]),
            {noreply, NewMoney};
        false ->
            %% 支取失败 提示余额不足
            io:format("Insufficient balance, current money is ~w", [Money]),
            {noreply, Money}
    end;
%%.

%%'扣年费（这里假设10秒为一年）
handle_info({yearly, Payment}, Money) ->
    Year = case get(year) of
        undefined -> 
            put(year, 0),
            0;
        Y -> 
            YY = Y + 1,
            put(year, YY),
            YY
    end,
    erlang:send_after(?YEAR_TIME * 1000, self(), {yearly, Payment}),
    Reply = if 
        Money =< 0 ->
            %% 没有钱可以扣
            Money;
        Year =:= 0 ->
            %% 还不到一年，不用扣
            Money;
        true ->
            NewMoney = Money - Payment,
            case NewMoney > 0 of
                true ->
                    %% 扣费成功
                    %% ?I("Yearly Payment: ~w -> ~w", [Money, NewMoney]),
                    %% 通知银行服务中心收取年费
                    bank_center ! {yearly_payment, Payment},
                    NewMoney;
                false ->
                    %% 余额不足以扣年费，则扣到0为止
                    %% ?I("Yearly Payment: ~w -> ~w", [Money, 0]),
                    %% 通知银行服务中心收取年费
                    bank_center ! {yearly_payment, Money},
                    0
            end
    end,
    {noreply, Reply};
%%.

%%'查询
handle_info(check, Money) ->
    io:format("Current money is: ~w", [Money]),
    {noreply, Money};

handle_info({From, check}, Money) ->
    %% ?I("Send result to: ~w", [From]),
    From ! {self(), Money},
    {noreply, Money};
%%.

handle_info(error, Money) ->
    %% Error Return ...
    {ok, Money};

handle_info(stop1, Money) ->
    {stop, "Force STOP", Money};

handle_info(stop2, Money) ->
    {stop, normal, Money};

handle_info(Info, State) ->
    io:format("handle_info: ~p~n", [Info]),
    {noreply, State}.

terminate(Reason, _State) ->
    io:format("terminate: ~p~n", [Reason]),
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

